#ifndef UL_UTIL_H_ 
#define UL_UTIL_H_
#include "ul_define.h"
#include <algorithm>
#include <pthread.h>
#include <sys/time.h>
namespace LinuxNetworkUtility
{
  void ul_usleep(int64_t sleep_us);

  bool ul_check_fd_readable(const int fd, const int64_t timeout_us = 0);

  int64_t ul_gettimeofday();

  enum
  {
    PRIME_NUM = 28
  };

  static const int64_t PRIME_LIST[PRIME_NUM] =
  {
    53l,         97l,         193l,       389l,       769l,
    1543l,       3079l,       6151l,      12289l,     24593l,
    49157l,      98317l,      196613l,    393241l,    786433l,
    1572869l,    3145739l,    6291469l,   12582917l,  25165843l,
    50331653l,   100663319l,  201326611l, 402653189l, 805306457l,
    1610612741l, 3221225473l, 4294967291l
  };

  inline int64_t ul_cal_next_prime(int64_t n)
  {
    int64_t ret = n;
    if (n > 0)
    {
      const int64_t* first = PRIME_LIST;
      const int64_t* last = PRIME_LIST + PRIME_NUM;
      const int64_t* pos = std::lower_bound(first, last, n);
      ret = ((pos == last) ? *(last - 1) : *pos);
    }
    return ret;
  }

  inline void ul_make_abstime(struct timespec &abstime, int64_t add_usec)
  {
    struct timeval now;
    const int64_t  num_usec_per_sec = 1000000;
    bool is_minus = (add_usec < 0);
    gettimeofday(&now,NULL);
    if (is_minus)
    {
      add_usec = -1*add_usec;
      int64_t sec = add_usec/num_usec_per_sec;
      now.tv_sec -= sec;
      add_usec -= num_usec_per_sec*sec;
      if (add_usec > now.tv_usec)
      {
        now.tv_sec --;
        now.tv_usec += num_usec_per_sec - add_usec;
      }
      else
      {
        now.tv_usec  -= add_usec;
      }
    }
    else
    {
      int sec = (add_usec + now.tv_usec)/num_usec_per_sec;
      now.tv_sec += sec;
      now.tv_usec += add_usec - sec*num_usec_per_sec;
    }
    abstime.tv_sec = now.tv_sec;
    abstime.tv_nsec = now.tv_usec * 1000;
  }
}   
#endif /* UL_UTIL_H_ */
